package com.vichat.task;

import com.vichat.task.entity.CfgTask;
import com.vichat.task.service.ITaskService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;

@Component("taskFrameWork")
public class TaskFrameWork
{
    private static transient Log log = LogFactory.getLog(TaskFrameWork.class);
    public static final String TASK_TYPE = "TASK_TYPE";
    public static final String TASK_ID = "TASK_ID";
    public static final String TASK_JOB_GROUP = "TASK_JOB_GROUP";
    public static final String TASK_TRIGGER_GROUP = "TASK_TRIGGER_GROUP";
    public static final String TASK_METHOD_FIXED = "F";
    public static final String TASK_METHOD_IMMEDIATE = "I";
    public static final String TASK_METHOD_CRON = "C";
    public static final String TASK_METHOD_MAIN = "M";
    public static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Autowired
    private ITaskService taskService;

    public  void main(String taskType)
            throws Exception
    {

        log.info("提醒:由于在一个线程中使用的数据库连接可能超过1个，请至少配置的连接池的最大数量为线程数量的1.5倍!");

        long bootPauseSeconds = 3L;

        log.info("启动暂停时间为:" + bootPauseSeconds + "秒");
        SchedulerFactory objSchedulerFactory = new StdSchedulerFactory();
        Scheduler objScheduler = objSchedulerFactory.getScheduler();
        try {
            _execute(objScheduler, taskType);
        }
        catch (Exception ex) {
            log.error("扫描作业加入失败,系统退出", ex);
            System.exit(-1);
        }

        log.info("开始启动调度系统…………");
        objScheduler.start();

        Thread.currentThread();
        Thread.sleep(bootPauseSeconds);
        log.info("启动调度系统完成");


    }



    private  void _execute(Scheduler objScheduler, String taskType) throws Exception {
        log.info("扫描任务执行");

        List<CfgTask> cfgTaskList = taskService.getCfgTaskByTaskType(taskType);

        if ((cfgTaskList == null) || (cfgTaskList.size() == 0)) {
            log.info("扫描到符合要求的任务为零,这次不处理");
            return;
        }

        for (CfgTask cfgTask : cfgTaskList) {
            try {

                String jobName = "job_" + cfgTask.getCfgTaskId();
                String triggerName = "trigger_" + cfgTask.getCfgTaskId();
                JobDetail job = JobBuilder.newJob(TaskJob.class).withIdentity(jobName, "TASK_JOB_GROUP").build();


                Trigger trigger = null;

                if (cfgTask.getTaskMethod().equalsIgnoreCase(TASK_METHOD_MAIN)) {
                    trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, TASK_TRIGGER_GROUP).startNow().build();
                }
                else if (cfgTask.getTaskMethod().equalsIgnoreCase(TASK_METHOD_CRON)) {
                    String cron = cfgTask.getTaskExpr();
                    if (StringUtils.isBlank(cron)) {
                        log.error("任务ID:" + cfgTask.getCfgTaskId() + ",配置的周期执行时间为空");
                        continue;
                    }
                    trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, TASK_TRIGGER_GROUP) .withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();

                }
                else if (cfgTask.getTaskMethod().equalsIgnoreCase(TASK_METHOD_FIXED)) {
                    try {
                        trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, TASK_TRIGGER_GROUP).startAt(DATE_FORMAT.parse(cfgTask.getTaskExpr())).build();
                    }
                    catch (Exception ex) {
                        log.error("任务ID:" + cfgTask.getCfgTaskId() + ",配置的固定执行时间错误", ex);
                        continue;
                    }
                }
                else {
                    log.error("任务ID:" + cfgTask.getCfgTaskId() + ",配置的task_method类型不为M，不进行调度处理");
                    continue;
                }

                job.getJobDataMap().put("TASK_ID", new Long(cfgTask.getCfgTaskId()));
                objScheduler.scheduleJob(job, trigger);


                log.info("加入调度的TASK_ID:" + cfgTask.getCfgTaskId()+", TASK_NAME:"+cfgTask.getTaskName()+", TASK_METHOD:"+cfgTask.getTaskMethod()+", TASK_EXPR:"+cfgTask.getTaskExpr());
            }

            catch (Exception ex1) {
                log.error("任务ID:" + cfgTask.getCfgTaskId() + ",无法调度", ex1);
            }
        }
    }



}

